////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef glmatrix_h__
#define glmatrix_h__

#if defined RE_USE_DX || defined RE_USE_SSE
#else

#include "core/types.h"
#include "math/scalar.h"
#include "math/quaternion.h"
#include "math/plane.h"

namespace Math
{
	class quaternion;
	class plane;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	matrix
	///
	/// \brief	Matrix 44. 
	///
	/// \author	Markus
	/// \date	17.02.2010
	////////////////////////////////////////////////////////////////////////////////////////////////////
	__declspec(align(16))
	class matrix
	{
	public:

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	matrix()
		///
		/// \brief	Default constructor. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		matrix();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	matrix(const float4 & r1, const float4 & r2, const float4 & r3, const float4 & r4)
		///
		/// \brief	Constructor. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r1	The first const float4 &. 
		/// \param	r2	The second const float4 &. 
		/// \param	r3	The third const float4 &. 
		/// \param	r4	The fourth const float4 &. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		matrix(const float4 & r1, const float4 & r2, const float4 & r3, const float4 & r4);






		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void operator= (const matrix & rhs)
		///
		/// \brief	Copy operator. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	rhs	The right hand side. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void operator = (const matrix & rhs);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool operator== (const matrix & rhs) const
		///
		/// \brief	Equality operator. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	rhs	The right hand side. 
		///
		/// \return	true if the parameters are considered equivalent. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool operator == (const matrix & rhs) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool operator!= (const matrix & rhs) const
		///
		/// \brief	Inequality operator. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	rhs	The right hand side. 
		///
		/// \return	true if the parameters are not considered equivalent. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool operator != (const matrix & rhs) const;






		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void set(const float4 & r1, const float4 & r2, const float4 & r3, const float4 & r4)
		///
		/// \brief	Sets. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r1	The const float4 & to set. 
		/// \param	r2	The const float4 & to set. 
		/// \param	r3	The const float4 & to set. 
		/// \param	r4	The const float4 & to set. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void set(const float4 & r1, const float4 & r2, const float4 & r3, const float4 & r4);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setr1(const float4 & r)
		///
		/// \brief	Setr 1. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setr1(const float4 & r);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setr2(const float4 & r)
		///
		/// \brief	Setr 2. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setr2(const float4 & r);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setr3(const float4 & r)
		///
		/// \brief	Setr 3. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setr3(const float4 & r);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setr4(const float4 & r)
		///
		/// \brief	Setr 4. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	r	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setr4(const float4 & r);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getr1() const
		///
		/// \brief	Getr 1. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getr1() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getr2() const
		///
		/// \brief	Getr 2. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getr2() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getr3() const
		///
		/// \brief	Getr 3. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getr3() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getr4() const
		///
		/// \brief	Getr 4. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getr4() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setxaxis(const float4 & a)
		///
		/// \brief	Setxaxis. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setxaxis(const float4 & a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setyaxis(const float4 & a)
		///
		/// \brief	Setyaxis. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setyaxis(const float4 & a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setzaxis(const float4 & a)
		///
		/// \brief	Setzaxis. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setzaxis(const float4 & a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void setposition(const float4 & pos)
		///
		/// \brief	Setpositions. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	pos	The position. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void setposition(const float4 & pos);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getxaxis() const
		///
		/// \brief	Getxaxis this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getxaxis() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getyaxis() const
		///
		/// \brief	Getyaxis this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getyaxis() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getzaxis() const
		///
		/// \brief	Getzaxis this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getzaxis() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	const float4 & getposition() const
		///
		/// \brief	Getpositions this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		const float4 & getposition() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void scale(const float4 & s)
		///
		/// \brief	Scales. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	s	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void scale(const float4 & s);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void translate(const float4 & f)
		///
		/// \brief	Translates. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	f	The. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void translate(const float4 & f);






		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool isidentity() const
		///
		/// \brief	Query if this object isidentity. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	true if it succeeds, false if it fails. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool isidentity() const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	scalar determinant() const
		///
		/// \brief	Determinants this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		scalar determinant() const;







		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix identity()
		///
		/// \brief	Identities this object. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix identity();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix affinetransformation(scalar s, const float4 & rC, const quaternion & r,
		/// 	const float4 & t)
		///
		/// \brief	Affinetransformations. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	s	The. 
		/// \param	rC	The c. 
		/// \param	r	The. 
		/// \param	t	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix affinetransformation(scalar s, const float4 & rC, const quaternion & r, const float4 & t);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix inverse(const matrix & m)
		///
		/// \brief	Inverses. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	m	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix inverse(const matrix & m);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix multiply(const matrix & m1, const matrix & m2)
		///
		/// \brief	Multiplies. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	m1	The first const matrix &. 
		/// \param	m2	The second const matrix &. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix multiply(const matrix & m1, const matrix & m2);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix lookatlh(const float4 & eye, const float4 & at, const float4 & up)
		///
		/// \brief	Lookatlhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	eye	The eye. 
		/// \param	at	at. 
		/// \param	up	The up. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix lookatlh(const float4 & eye, const float4 & at, const float4 & up);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix lookatrh(const float4 & eye, const float4 & at, const float4 & up)
		///
		/// \brief	Lookatrhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	eye	The eye. 
		/// \param	at	at. 
		/// \param	up	The up. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix lookatrh(const float4 & eye, const float4 & at, const float4 & up);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix ortholh(scalar w, scalar h, scalar zn, scalar zf)
		///
		/// \brief	Ortholhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	w	The w. 
		/// \param	h	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix ortholh(scalar w, scalar h, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix orthorh(scalar w, scalar h, scalar zn, scalar zf)
		///
		/// \brief	Orthorhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	w	The w. 
		/// \param	h	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix orthorh(scalar w, scalar h, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix orthooffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn,
		/// 	scalar zf)
		///
		/// \brief	Orthooffcenterlhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	l	The. 
		/// \param	r	The. 
		/// \param	b	The. 
		/// \param	t	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix orthooffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix orthooffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn,
		/// 	scalar zf)
		///
		/// \brief	Orthooffcenterrhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	l	The. 
		/// \param	r	The. 
		/// \param	b	The. 
		/// \param	t	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix orthooffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectivefovlh(scalar fovy, scalar aspect, scalar zn, scalar zf)
		///
		/// \brief	Perspectivefovlhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	fovy	The fovy. 
		/// \param	aspect	The aspect. 
		/// \param	zn		The zn. 
		/// \param	zf		The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectivefovlh(scalar fovy, scalar aspect, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectivefovrh(scalar fovy, scalar aspect, scalar zn, scalar zf)
		///
		/// \brief	Perspectivefovrhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	fovy	The fovy. 
		/// \param	aspect	The aspect. 
		/// \param	zn		The zn. 
		/// \param	zf		The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectivefovrh(scalar fovy, scalar aspect, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectivelh(scalar w, scalar h, scalar zn, scalar zf)
		///
		/// \brief	Perspectivelhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	w	The w. 
		/// \param	h	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectivelh(scalar w, scalar h, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectiverh(scalar w, scalar h, scalar zn, scalar zf)
		///
		/// \brief	Perspectiverhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	w	The w. 
		/// \param	h	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectiverh(scalar w, scalar h, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectiveoffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn,
		/// 	scalar zf)
		///
		/// \brief	Perspectiveoffcenterlhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	l	The. 
		/// \param	r	The. 
		/// \param	b	The. 
		/// \param	t	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectiveoffcenterlh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix perspectiveoffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn,
		/// 	scalar zf)
		///
		/// \brief	Perspectiveoffcenterrhes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	l	The. 
		/// \param	r	The. 
		/// \param	b	The. 
		/// \param	t	The. 
		/// \param	zn	The zn. 
		/// \param	zf	The zf. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix perspectiveoffcenterrh(scalar l, scalar r, scalar b, scalar t, scalar zn, scalar zf);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix reflect(const plane & p)
		///
		/// \brief	Reflects. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	p	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix reflect(const plane & p);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationaxis(const float4 & axis, scalar angle)
		///
		/// \brief	Rotateaxis. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	axis	The axis. 
		/// \param	angle	The angle. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationaxis(const float4 & axis, scalar angle);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationquaternion(const quaternion & q)
		///
		/// \brief	Rotatequaternions. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	q	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationquaternion(const quaternion & q);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationx(scalar a)
		///
		/// \brief	Rotatexes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationx(scalar a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationy(scalar a)
		///
		/// \brief	Rotateys. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationy(scalar a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationz(scalar a)
		///
		/// \brief	Rotatezs. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	a	a. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationz(scalar a);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix rotationpitchyawroll(scalar pitch, scalar yaw, scalar roll)
		///
		/// \brief	Rotatepitchyawrolls. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	pitch	The pitch. 
		/// \param	yaw		The yaw. 
		/// \param	roll	The roll. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix rotationpitchyawroll(scalar pitch, scalar yaw, scalar roll);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix scaling(scalar sx, scalar sy, scalar sz)
		///
		/// \brief	Scalings. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	sx	The sx. 
		/// \param	sy	The sy. 
		/// \param	sz	The size. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix scaling(scalar sx, scalar sy, scalar sz);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix scaling(const float4 & s)
		///
		/// \brief	Scalings. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	s	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix scaling(const float4 & s);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix transformation(const float4 & sC, const quaternion &sR, const float4 & s,
		/// 	const float4 & rC, const quaterrion & r, const float4 & t)
		///
		/// \brief	Transformations. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	sC	The c. 
		/// \param	sR	The r. 
		/// \param	s	The. 
		/// \param	rC	The c. 
		/// \param	r	The. 
		/// \param	t	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix transformation(const float4 & sC, const quaternion &sR, const float4 & s, const float4 & rC, const quaternion & r, const float4 & t);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix translation(scalar x, scalar y, scalar z)
		///
		/// \brief	Translations. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	x	The x coordinate. 
		/// \param	y	The y coordinate. 
		/// \param	z	The z coordinate. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix translation(scalar x, scalar y, scalar z);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static matrix transpose(const matrix & m)
		///
		/// \brief	Transposes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	m	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static matrix transpose(const matrix & m);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static float4 transform(const float4 & f, const matrix & m)
		///
		/// \brief	Transforms. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	f	The. 
		/// \param	m	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static float4 transform(const float4 & f, const matrix & m);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static quaternion rotationmatrix(const matrix & m)
		///
		/// \brief	Rotationmatrixes. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	m	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static quaternion rotationmatrix(const matrix & m);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	static plane transform(const plane & p, const matrix & m)
		///
		/// \brief	Transforms. 
		///
		/// \author	Markus
		/// \date	17.02.2010
		///
		/// \param	p	The. 
		/// \param	m	The. 
		///
		/// \return	. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		static plane transform(const plane & p, const matrix & m);



	protected:

		float4 m_row1;
		float4 m_row2;
		float4 m_row3;
		float4 m_row4;


		friend class plane;
		friend class quaternion;
		friend class float4;

	private:

	};

}

#endif //

#endif // glmatrix_h__